home *** CD-ROM | disk | FTP | other *** search
- #include <ConsLaw.h>
- #include <MenuSystem.h>
- #include <createHCLSchemes.h>
- #include <createFluxFunc.h>
- #include <createInitFunc.h>
- #include <DrawFD.h>
-
- ConsLaw:: ConsLaw ()
- { p_value = 0; /* gives p=1 field due to exp(0) */ }
-
- BooLean ConsLaw:: ok () const
- {
- BooLean b = dpTRUE;
- HANDLE_OK("ConsLaw::ok",u,b)
- HANDLE_OK("ConsLaw::ok",u_prev,b)
- HANDLE_OK("ConsLaw::ok",p,b)
- if (!scheme.ok()) { b = dpFALSE;
- errorFP("ConsLaw::ok","scheme is not rebinded to a field (empty handle)");}
- if (!flux.ok()) { b = dpFALSE;
- errorFP("ConsLaw::ok","flux is not rebinded (empty handle)"); }
- if (time_points_for_plot.getNoMembers() < 1)
- warningFP("ConsLaw::ok","no plots will be made! (no time points given)");
- return b;
- }
-
- void ConsLaw:: adm (MenuSystem& menu)
- {
- define (global_menu); // define menu items
- global_menu.prompt(); // prompt the user (read input data)
- scan (global_menu); // load user's input data into the class variables
- }
-
- void ConsLaw:: solveProblem ()
- {
- if (!ok())
- fatalerrorFP("ConsLaw::driver",
- "object is not properly initialized, have you called adm?");
- setIC (); // set initial conditions
- timeLoop (); // perform time stepping
- }
-
- void ConsLaw:: define (MenuSystem& menu, int level)
- {
- menu.addItem (level, // menu level (main, submenu, subsubmenu)
- "grid", // item name, used as command
- "grid", // corresponding Unix cml arg., +grid
- "GridLattice::scan syntax", // help/description
- "d=1, domain: [0,1] index: [0:20]", // default answer
- "S", // indicates that valid answer is a string
- 'g', 'g'); // short forms (-g instead of +grid etc)
- menu.addItem (level,
- "time parameters",
- "timeprm",
- "TimePrm::scan syntax",
- "dt=0.05, t in [0,0.9]",
- "S",
- 't','t');
- menu.addItem (level,
- "time points for plot",
- "plot_times",
- "Set::scan syntax, eoi: <CR>",
- "0.2 0.5 0.8",
- "S", // improvement: could be intelligent from t in [0:?]
- 'p','p');
- menu.addItem (level,
- "scheme",
- "scheme",
- "classname in HCLSchemes hierarchy",
- "UpwindScheme1D",
- validationString(hierHCLSchemes()),
- 's','s');
-
- menu.addItem (level,
- "flux function",
- "flux",
- "functor, name in FluxFunc hierarchy",
- "FluxLinear",
- validationString(hierFluxFunc()),
- 'f','f');
- menu.addItem (level,
- "initial function",
- "u0",
- "functor, name in InitFunc hierarchy",
- "InitConst1",
- validationString(hierInitFunc()),
- '0','0');
- menu.addItem (level,
- "uL",
- "uL",
- "value of u(x,t) at the left boundary",
- "1",
- "R1",
- 'l','l');
- menu.addItem (level,
- "p-mean",
- "E[p]",
- "mean value of the p-field (f(u;p))",
- "0",
- "R1",
- 'P','P');
- }
-
- void ConsLaw:: scan (MenuSystem& menu)
- {
- grid.rebind (new GridLattice(1)); grid->scan (menu.get("grid"));
- u.rebind (new FieldFD (grid(), "u"));
- u_prev.rebind (new FieldFD (grid(), "u_prev"));
- tip.scan (menu.get("time parameters"));
- // add the end mark ';' to the end (required by TimePrm::scan):
- time_points_for_plot.scan (menu.get("time points for plot") + " ;");
- flux_tp = menu.get("flux function");
- flux.rebind (createFluxFunc(flux_tp,*this));
-
- u0_tp = menu.get("initial function");
- u0.rebind (createInitFunc(u0_tp,*this));
-
- uL = menu.get("uL").getReal();
- u->valueIndex(0) = u_prev->valueIndex(0) = uL;
-
- scheme_tp = menu.get("scheme"); // scheme type
- scheme.rebind (createHCLSchemes (scheme_tp, *this));
-
- // p-field, set p = exp(p_value):
- p.rebind (new FieldFD (grid(), "p"));
- p_value = menu.get("p-mean").getReal();
- p->fill (exp(p_value));
-
- file.open (CaseName); // plot file name:
-
- // write input data for a check:
- s_o << "-------------- these input data were read ---------------\n";
- u->grid().print(s_o); tip.print(s_o);
- s_o << "Making plots at time points: "; time_points_for_plot.print (s_o);
- s_o << "Flux function : " << flux_tp << "\ninitial function = ";
- s_o << u0_tp << " uL=" << uL << '\n';
- s_o << "---------------------------------------------------------\n";
- }
-
- void ConsLaw:: setIC ()
- {
- u_prev() = u0();
- u_prev->valueIndex(grid->getBase(1)) = uL;
-
- // --- find the suitable dt ---
- real dt;
- real pmin, pmax;
- p->minmax (pmin, pmax);
-
- if (flux_tp == "FluxLinear")
- {
- if (tip.Delta() > grid->Delta(1)/pmin)
- dt = grid->Delta(1)/pmin;
- else
- dt = tip.Delta();
- }
- else if (flux_tp == "FluxSimpleBuckleyLeverett" || flux_tp == "FluxBurger")
- dt = grid->Delta(1) / maxFluxDeriv (flux(),0,uL,0,0,0.1,0.1);
- else if (flux_tp == "FluxBuckleyLeverett")
- {
- real pdelta;
- if (pmin == pmax)
- pdelta = 10; // void infinite loop in maxFluxDeriv!
- else if (pmax > pmin)
- pdelta = pmax - pmin;
- else
- errorFP("ConsLaw::setIC","pmax=%f < pmin=%f ....",pmax,pmin);
-
- dt = grid->Delta(1) / maxFluxDeriv (flux(),0,uL,pmin,pmax,
- 0.1,pdelta/10.0);
- }
- tip.setTimeStep (dt); // store the computed dt in the TimePrm object
- }
-
- void ConsLaw:: timeLoop ()
- {
- tip.initTimeLoop();
- while (!tip.finished()) {
- tip.increaseTime();
- solveAtThisTimeLevel ();
- saveResults ();
- updateDataStructures ();
- }
- }
-
- void ConsLaw:: solveAtThisTimeLevel ()
- {
- scheme->update (); // execute the difference scheme
- u->valueIndex(grid->getBase(1)) = uL; // set boundary conditions afterwards
- }
-
- void ConsLaw:: saveResults ()
- {
- if (time_points_for_plot.within (tip.getTime(), 0.4999*tip.Delta()))
- DrawFD::makeCurvPlot (u(),file,"u(x) for t fixed","u",
- oform("t=%g",tip.getTime()));
- }
-
- void ConsLaw:: updateDataStructures () { u_prev() = u(); }
-